package cn.edu.sdjzu.xg.bysj.controller.basic;

import cn.edu.sdjzu.xg.bysj.domain.GraduateProject;
import cn.edu.sdjzu.xg.bysj.service.GraduateProjectService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import exception.BysjException;
import lombok.extern.slf4j.Slf4j;
import util.Condition;
import util.JSONUtil;
import util.Pagination;
import util.ControllerHelper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

@Slf4j
@WebServlet("/graduateProject.ctl")
public class GraduateProjectController extends HttpServlet {
    /**
     * 把一个或所有符合条件教师对象以分页的形式响应到前端
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException      可能的请求
     *                          {"id":1}
     *                          可能的请求
     *                          {
     *                          "pagination": {
     *                          "pageNo": 2,
     *                          "pageSize": 2
     *                          },
     *                          "conditionList": [{
     *                          "value": "9",
     *                          "key": "name",
     *                          "operator": "LIKE"
     *                          },
     *                          {
     *                          "value": "9",
     *                          "key": "department_id",
     *                          "operator": "="
     *                          }
     *                          ]
     *                          }
     */
    @Override
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response)
            throws ServletException, IOException {
        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();


        //将request body转换为JSON字串
        String req_jsonStr = JSONUtil.getJSON(request);
        //将request body解析为JSONObject对象
        JSONObject req_jsonObj = JSON.parseObject(req_jsonStr);
        //如果请求body为空
        if (req_jsonObj == null) {
            respMessage_jsonObj.put("message", "未收到请求信息！");
            response.getWriter().println(respMessage_jsonObj);
            return;
        }
        //从JSONObject对象中读取键“id”的值（Java Object对象），req_jsonObj可能是{"id":1}
        Object id_obj = req_jsonObj.get("id");
        try {
            //如果id_Obj != null, 说明请求数据有id键，是请求某个教师对象
            if (id_obj != null) {
                int id_int = Integer.parseInt(id_obj.toString());
                responseGraduateProject(id_int, response);
            } else {//请求中包含条件和分页信息，需要响应多个教师对象
                //读取分页信息，形成分页对象
                //从JSONObject对象中读取 “pagination” 键对应的值(JSONObject对象)
                Pagination pagination = ControllerHelper.getPagination(req_jsonObj);
                //从请求JSONObject对象中读取键“conditionList”对应的值(描述查询条件的JSONArray对象)
                List<Condition> conditionList = ControllerHelper.getConditions(req_jsonObj);
                //响应多个教师信息，其中conditionList, pagination两个对象引用为空是可能的
                this.responseGraduateProjects(response, conditionList, pagination);
            }

        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            log.debug(e.getMessage());
            log.error(e.getMessage(), e);
            //响应respMessage_jsonObj到前端
            response.getWriter().println(respMessage_jsonObj);
            //打印异常栈，方便调试（要用log4j代替）

        } catch (Exception e) {
            log.debug(e.getMessage());
            respMessage_jsonObj.put("message", "网络异常");
            //响应respMessage_jsonObj到前端
            response.getWriter().println(respMessage_jsonObj);
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage(), e);

        }
    }

    //按分页信息响应符合条件的教师对象和对象总数
    private void responseGraduateProjects(HttpServletResponse response,
                                          List<Condition> conditionList_json_str,
                                          Pagination pagination)
            throws ServletException, IOException, SQLException {
        //分页获得满足条件的所有教师
        Collection<GraduateProject> graduateProjects = GraduateProjectService.getInstance()
                .findAll(conditionList_json_str, pagination);
        //第二个参数可以防止循环引用
        String graduateProjects_jsonStr = JSON.toJSONString(graduateProjects,
                SerializerFeature.DisableCircularReferenceDetect);
        //创建JSON对象resp_jsonObj，以便往前端响应综合信息
        JSONObject resp_jsonObj = new JSONObject();
        resp_jsonObj.put("totalNum", pagination.getTotalNum());
        resp_jsonObj.put("data", graduateProjects_jsonStr);
        //响应resp_jsonObj到前端
        response.getWriter().println(resp_jsonObj);
    }

    //响应一个教师对象
    private void responseGraduateProject(int id, HttpServletResponse response)
            throws ServletException, IOException, SQLException {
        //根据id查找教师
        GraduateProject graduateProject = GraduateProjectService.getInstance().find(id);
        String graduateProject_jsonStr = JSON.toJSONString(graduateProject);

        //响应graduateProject_json到前端
        response.getWriter().println(graduateProject_jsonStr);
    }

    //请使用以下JSON测试增加功能
    //{"graduateProject":{"description":"博士","id":1,"no":"01","remarks":""},"department":{"description":"信息管理","id":2,"no":"0202","remarks":"","teacher":{"description":"管理工程","id":2,"no":"02","remarks":"最好的教师"}},"id":7,"name":"id=7 的新的新老师","title":{"description":"副教授","id":2,"no":"02","remarks":""}}
    //请使用以下JSON测试修改功能
    //{"description":"修改id=1的老师
    //{"graduateProject":{"description":"博士","id":1,"no":"01","remarks":""},"department":{"description":"信息管理","id":2,"no":"0202","remarks":"","teacher":{"description":"管理工程","id":2,"no":"02","remarks":"最好的教师"}},"id":1,"name":"修改id=1的老师","title":{"description":"副教授","id":2,"no":"02","remarks":""}}

    /**
     * POST, http://localhost:8080/graduateProject.ctl, 增加教师
     * 增加一个教师对象：将来自前端请求的JSON对象，增加到数据库表中
     *
     * @param request  请求对象
     * @param response 响应对象
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response)
            throws ServletException, IOException {

        //根据request对象，获得代表新增GraduateProject的JSON字串
        String req_graduateProjectToAdd_jsonStr = JSONUtil.getJSON(request);
        //将JSON字串解析为GraduateProject对象
        GraduateProject graduateProjectToAdd = JSON.parseObject(req_graduateProjectToAdd_jsonStr,
                GraduateProject.class);

        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        try {
            //在数据库表中增加GraduateProject对象
            GraduateProjectService.getInstance().add(graduateProjectToAdd);
            respMessage_jsonObj.put("message", "增加成功");
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage(), e);
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage(), e);
        }
        //响应respMessage_jsonObj到前端
        response.getWriter().println(respMessage_jsonObj);
    }

    /**
     * DELETE, http://localhost:8080/graduateProject.ctl?id=1, 删除id=1的教师
     * 删除一个教师对象：根据来自前端请求的id，删除数据库表中id的对应记录
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doDelete(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //将request参数转换为JSON字串
        String request_json_str = JSONUtil.getJSON(request);
        //将请求body解析为要删除的GraduateProject的id对应的JSONObject对象(可能是{"id":1})
        JSONObject GraduateProjectToDelete_jsonObj = JSON.parseObject(request_json_str);
        //从JSONObject对象中读取键“id”的值（Java Object对象），
        Object id_obj = GraduateProjectToDelete_jsonObj.get("id");

        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        try {
            if(id_obj!=null){
                //到数据库表中删除对应的教师
                int id_int = Integer.parseInt(id_obj.toString());
                GraduateProjectService.getInstance().delete(id_int);
            }
            else {
                //从JSONObject对象中读取键“id”的值（Java Object对象），
                JSONArray graduateProjects_jsonArray =
                        GraduateProjectToDelete_jsonObj.getJSONArray("graduateProjects");
                List<GraduateProject> List = graduateProjects_jsonArray.toJavaList(GraduateProject.class);
                GraduateProjectService.getInstance().delete(List);
            }
            respMessage_jsonObj.put("message", "删除成功");
        } catch (BysjException e) {
            log.debug(e.getMessage());
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage(), e);
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage(), e);
        }
        //响应respMessage_jsonObj到前端
        response.getWriter().println(respMessage_jsonObj);
    }


    /**
     * PUT, http://localhost:8080/graduateProject.ctl, 修改教师
     * <p>
     * 修改一个教师对象：将来自前端请求的JSON对象，更新数据库表中相同id的记录
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPut(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String graduateProjectToUpdate_jsonStr = JSONUtil.getJSON(request);
        //将JSON字串解析为要修改的GraduateProject对象（有id的完整对象）
        GraduateProject graduateProjectToUpdate =
                JSON.parseObject(graduateProjectToUpdate_jsonStr, GraduateProject.class);

        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        try {
            //到数据库表修改GraduateProject对象对应的记录
            GraduateProjectService.getInstance().update(graduateProjectToUpdate);
            respMessage_jsonObj.put("message", "修改成功");
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage(), e);
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //打印异常栈，方便调试（要用log4j代替）
            log.error(e.getMessage(), e);
        }
        //响应respMessage_jsonObj到前端
        response.getWriter().println(respMessage_jsonObj);
    }
}
